local ymh_shadow_brain = require("brains/ymh_shadow_brain")

local function OnRippleAnimOver(inst)
    if inst.pool.invalid then
        inst:Remove()
    else
        inst:Hide()
        table.insert(inst.pool, inst)
    end
end

local function CreateRipple(pool)
    local inst
    if #pool > 0 then
        inst = table.remove(pool)
        inst:Show()
    else
        inst = CreateEntity()

        inst:AddTag("FX")
        inst:AddTag("NOCLICK")
        --[[Non-networked entity]]
        inst.entity:SetCanSleep(false)
        inst.persists = false

        inst.entity:AddTransform()
        inst.entity:AddAnimState()

        inst.AnimState:SetBank("splash_weregoose_fx")
        inst.AnimState:SetBuild("splash_water_drop")
        inst.AnimState:SetLayer(LAYER_WORLD_BACKGROUND)
        inst.AnimState:SetOceanBlendParams(TUNING.OCEAN_SHADER.EFFECT_TINT_AMOUNT)

        inst.pool = pool
        inst:ListenForEvent("animover", OnRippleAnimOver)
    end

    inst.AnimState:PlayAnimation(math.random() < .5 and "no_splash" or "no_splash2")
    local scale = .6 + math.random() * .2
    inst.AnimState:SetScale(math.random() < .5 and -scale or scale, scale)

    return inst
end

local function DropAggro(inst)
    local leader = inst.components.follower:GetLeader()
    if leader ~= nil and
        ((leader.components.health ~= nil and leader.components.health:IsDead()) or
            (leader.sg ~= nil and leader.sg:HasStateTag("hiding")) or
            not inst:IsNear(leader, TUNING.SHADOWWAXWELL_PROTECTOR_TRANSFER_AGGRO_RANGE) or
            not leader.entity:IsVisible() or
            leader:HasTag("playerghost")
        ) then
        --dead, hiding, or too far
        leader = nil
    end
    --nil leader will just drop target
    inst:PushEvent("transfercombattarget", leader)
end
local function TryRipple(inst, map)
    if not (inst:HasTag("moving") or
            inst.AnimState:IsCurrentAnimation("appear") or
            inst.AnimState:IsCurrentAnimation("disappear") or
            inst.AnimState:IsCurrentAnimation("lunge_pst")
        ) then
        local x, y, z = inst.Transform:GetWorldPosition()
        if map:IsOceanAtPoint(x, 0, z) then
            CreateRipple(inst.ripple_pool).Transform:SetPosition(x, 0, z)
        end
    end
end

local function OnAttacked(inst, data)
    if data.attacker ~= nil then
        -- if data.attacker.components.petleash ~= nil and
        --     data.attacker.components.petleash:IsPet(inst) then
        --     if inst.despawnpetloot then
        --         if inst.components.lootdropper == nil then
        --             inst:AddComponent("lootdropper")
        --         end
        --         inst.components.lootdropper:SpawnLootPrefab("nightmarefuel", inst:GetPosition())
        --     end
        --     data.attacker.components.petleash:DespawnPet(inst)
        if inst.components.follower.leader ~= nil and data.attacker == inst.components.follower.leader then
            inst.components.health:Kill()
            return
        elseif data.attacker.components.combat ~= nil then
            inst.components.combat:SuggestTarget(data.attacker)
        end
    end
end
local function killed(inst, data)
    local victim = data and data.victim
    local hp = victim and victim.components.health and victim.components.health.maxhealth
    if hp and hp > 0 then
        if inst.components.health then
            inst.components.health:DoDelta(hp,true)
        end
        local player = inst.yuemiheng_owner
        if player and player:HasTag('player') and player.components.ymh_lv then
            local exp = hp and hp/TUNING.MOD_YUEMIHENG.AVATAR.YUEMIHENG.EXP.PER_EXP_FROM_MOB_HP
            player.components.ymh_lv:GetExp(exp)
        end

    end


end
local RETARGET_MUST_TAGS = { "_combat" }
local function NormalRetargetFn(inst)
    if inst:HasTag("NPC_contestant") then
        return nil
    end

    local exclude_tags = { "playerghost", "INLIMBO", "NPC_contestant" }
    if inst.components.follower.leader ~= nil then
        table.insert(exclude_tags, "abigail")
    end
    if inst.components.minigame_spectator ~= nil then
        table.insert(exclude_tags, "player") -- prevent spectators from auto-targeting webber
    end

    local oneof_tags = { "monster", "wonkey", "pirate" }
    if not inst:HasTag("merm") then
        table.insert(oneof_tags, "merm")
    end

    return not inst:IsInLimbo()
        and FindEntity(
            inst,
            TUNING.PIG_TARGET_DIST,
            function(guy)
                return guy:IsInLight() and inst.components.combat:CanTarget(guy)
            end,
            RETARGET_MUST_TAGS, -- see entityreplica.lua
            exclude_tags,
            oneof_tags
        )
        or nil
end
local function NormalKeepTargetFn(inst, target)
    --give up on dead guys, or guys in the dark, or werepigs
    return inst.components.combat:CanTarget(target) and target:IsInLight()
        and not (target.sg ~= nil and target.sg:HasStateTag("transform"))
end

-- local function onsave(inst, data)

-- end

-- local function onload(inst, data)

-- end

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddSoundEmitter()
    inst.entity:AddNetwork()

    inst:SetPhysicsRadiusOverride(.5)                     -- 设置物理半径
    -- 这样就能导出乱跑了 这或许是一种更好的踏水实现
    MakeGhostPhysics(inst, 1, inst.physicsradiusoverride) -- 设定幽灵物理特性

    inst.Transform:SetFourFaced(inst)

    inst.AnimState:SetBank("wilson")
    inst.AnimState:SetBuild("waxwell")
    inst.AnimState:OverrideSymbol("fx_wipe", "wilson_fx", "fx_wipe")
    inst.AnimState:PlayAnimation("minion_spawn")
    inst.AnimState:SetMultColour(0, 0, 0, .5)
    inst.AnimState:UsePointFiltering(true)

    inst.AnimState:AddOverrideBuild("waxwell_minion_spawn")
    inst.AnimState:AddOverrideBuild("waxwell_minion_appear")
    -- local tool = { "swap_axe", "swap_pickaxe", "swap_shovel" }
    inst.AnimState:Hide("ARM_carry")
    -- if true then
    --     inst.AnimState:OverrideSymbol("swap_object", "swap_axe", "swap_axe")
    --     inst.AnimState:Hide("ARM_normal")
    -- else
    --     inst.AnimState:Hide("ARM_carry")
    -- end

    -- if hat ~= nil then
    --     inst.AnimState:OverrideSymbol("swap_hat", hat, "swap_hat")
    --     inst.AnimState:Hide("HAIR_NOHAT")
    --     inst.AnimState:Hide("HAIR")
    -- else
    --     inst.AnimState:Hide("HAT")
    --     inst.AnimState:Hide("HAIR_HAT")
    -- end

    -- inst:AddTag("scarytoprey")
    -- inst:AddTag("shadowminion")
    inst:AddTag("NOBLOCK")

    -- inst:SetPrefabNameOverride("shadowwaxwell") -- 设置预制名称覆盖

    -- 专用服务器不需要生成本地特效
    if not TheNet:IsDedicated() then
        inst.ripple_pool = {}
        inst:DoPeriodicTask(.6, TryRipple, math.random() * .6, TheWorld.Map) -- 定期任务
    end

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    inst:AddComponent("skinner")
    inst.components.skinner:SetupNonPlayerData()

    inst:AddComponent("locomotor")
    inst.components.locomotor.runspeed = TUNING.SHADOWWAXWELL_SPEED
    inst.components.locomotor:SetTriggersCreep(false)
    inst.components.locomotor.pathcaps = { ignorecreep = true }
    inst.components.locomotor:SetSlowMultiplier(.6)

    inst:AddComponent("health")
    inst.components.health:SetMaxHealth(6000)
    inst.components.health.nofadeout = true

    inst:AddComponent("combat")
    inst.components.combat.hiteffectsymbol = "torso"
    -- inst.components.combat:SetRange(2)
    -- inst.components.combat:SetAttackPeriod(0.5)
    -- inst.components.combat:SetDefaultDamage(50)
    inst.components.combat:SetDefaultDamage(40)
    inst.components.combat:SetAttackPeriod(.6)
    inst.components.combat:SetRetargetFunction(1, NormalRetargetFn)
    inst.components.combat:SetKeepTargetFunction(NormalKeepTargetFn)

    inst:AddComponent("follower")
    inst.components.follower:KeepLeaderOnAttacked()
    inst.components.follower.keepdeadleader = true
    inst.components.follower.keepleaderduringminigame = true
    inst.components.follower.maxfollowtime = 3600
    inst:AddComponent("timer")
    inst.components.timer:StartTimer("kouxue", 480)
    inst:ListenForEvent("timerdone", function(inst, data)
        if data and data.name == "kouxue" then
            if inst.components.health ~= nil then
                inst.components.health:DoDelta(-1000)
                inst.components.timer:StartTimer("kouxue", 480)
            end
        end
    end)

    inst:SetBrain(ymh_shadow_brain)                  -- 设置大脑
    inst:SetStateGraph("SGshadowwaxwell") -- 设置状态图
    -- inst:SetStateGraph("SGwilson")              -- 设置状态图

    inst:ListenForEvent("attacked", OnAttacked) -- 监听攻击事件
    inst:ListenForEvent("death", DropAggro)     -- 监听死亡事件
    inst:ListenForEvent("killed", killed)       -- 监听击杀事件
    inst:DoPeriodicTask(1, function()
        if inst.components.follower ~= nil and inst.components.follower.leader ~= nil then
            inst.AnimState:SetBuild(inst.components.follower.leader.AnimState:GetBuild())
        end
        if inst.components.combat ~= nil and inst.components.follower.leader ~= nil and inst.components.follower.leader.components.inventory ~= nil then
            local itematk = inst.components.follower.leader.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
            if itematk ~= nil then
                -- print("11111111111")
                -- print("当前伤害为" .. (itematk.components.weapon and itematk.components.weapon.damage) or
                --     40)
                inst.components.combat:SetDefaultDamage((itematk.components.weapon and itematk.components.weapon.damage) or
                    40)
            else
                -- print("2222")
                inst.components.combat:SetDefaultDamage(40)
            end
        end
        if inst.components.follower.leader == nil then
            inst.components.health:Kill()
        end
    end)
    inst.DropAggro = DropAggro

    inst:DoTaskInTime(8*60,function() -- 影子每八分钟减少1000血量（一次性
        if inst.components.health then
            inst.components.health:DoDelta(-1000)
        end
    end)

    -- inst.OnSave = onsave 
    -- inst.OnLoad = onload

    return inst
end
return Prefab("yuemiheng_shadow", fn, nil, nil)


